﻿// WMS Library - http://wmslib.codeplex.com/
// Copyright (c) Tom Gaskins 2004 - Erik Putrycz 2013
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WMSLib.Client;

namespace EPLabs.WeatherMaps
{
    public class ExtendedLayer
    {
        public ExtendedLayer(Layer l, bool isPast, bool isForecast)
        {
            _layer = l;
            _isPast = isPast;
            _isForecast = isForecast;
        }

        public List<Tuple<DateTime, Uri>> BuildAllURLs(int w, int h, Layer.BoundingBoxType bb, ImageType img)
        {
            var now = DateTime.Now;
            var uris = _layer.BuildAllURLs(w, h, bb, img);
            var all = uris.Where(tp => (now - tp.Item1).TotalMilliseconds >= 0).OrderBy(tp => (now - tp.Item1).TotalMilliseconds);
            if (all.Count() > 0)
            {
                _currentUri = all.First();
            }
            else
            {
                _currentUri = uris.First();
            }
            var currentTimestamp = _currentUri.Item1;
            if (!_isForecast)
            {
                uris.RemoveAll(p => p.Item1 > currentTimestamp);
            }
            if (!_isPast)
            {
                uris.RemoveAll(p => p.Item1 < currentTimestamp);
            }
            return uris;
        }

        public Tuple<DateTime, Uri> CurrentImage
        {
            get { return _currentUri; }
        }

        private Layer _layer;
        private Tuple<DateTime, Uri> _currentUri;
        private bool _isPast;
        private bool _isForecast;
        private DateTime _now;

        public Layer Layer
        {
            get { return _layer; }
        }

        public DateTime Now { get { return _now; } }

        public Tuple<List<Tuple<DateTime, string>>,int,int> TimeDividers(bool toUpper = true)
        {
            var dividers = new List<Tuple<DateTime, string>>();
            var range = _layer.ParseISOInterval();
            if (range == null)
                return null;
            var intervalMinutes = range.Item3.TotalMinutes;
            var intervalCount = range == null ? 0 : (int)((range.Item2 - range.Item1).TotalMinutes / range.Item3.TotalMinutes);
            var intervals = Enumerable.Range(0,intervalCount+1).Select(i => range.Item1.AddMinutes(i * intervalMinutes));
            var dtNow = DateTime.Now;
            _now = intervals.Where(ts => ts <= dtNow).OrderBy(ts => dtNow - ts).First();
            int pos = -1;
            if (_isPast && _isForecast)
            {
                dividers.Add(Tuple.Create(DateTime.MinValue, "Past & Forecast"));
                pos = 0;
            }
            if (_isPast)
            {
                var pRange = (int)(_now - range.Item1).TotalHours;
                if (pRange > 4)
                    dividers.Add(Tuple.Create(range.Item1, "Past " +pRange + " Hours"));
                dividers.Add(Tuple.Create(_now.AddHours(-4), "Past 4 Hours"));
                dividers.Add(Tuple.Create(_now.AddHours(-2), "Past 2 Hours"));
            }
            if (_isPast && !_isForecast)
                pos = 0;
            dividers.Add(Tuple.Create(_now, "Now"));
            if (pos == -1)
                pos = dividers.Count - 1;
            var nowPos = dividers.Count - 1;
            if (_isForecast)
            {
                dividers.Add(Tuple.Create(_now.AddHours(2), "Next 2 Hours"));
                dividers.Add(Tuple.Create(_now.AddHours(4), "Next 4 Hours"));
                var pRange = (int)(range.Item2 - _now).TotalHours;
                dividers.Add(Tuple.Create(range.Item2, "Next " + pRange + " Hours"));
            }
            if (!_isPast && _isForecast)
                pos = dividers.Count - 1;
            if (toUpper)
                dividers = dividers.Select(tp => Tuple.Create(tp.Item1, tp.Item2.ToUpper())).ToList();
            return Tuple.Create(dividers,pos,nowPos);
        }

    }
}
